﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using PcProject.Application.Service.Products;
using PcProject.Domain.IRepository;
using PcProject.Domain.Models.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MiniPc.API.log4net;
using PcProject.Application.Service.AutoMapper;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using Microsoft.AspNetCore.Authorization;
using MiniPc.API.MongoCRUD;
using PcProject.Application.Service.Userss;
using MiniPc.API.Jwt;

namespace MiniPc.API.Controllers
{
    /// <summary>
    /// 商品控制器
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    //[Authorize] //授权过滤
    public class ProductController : ControllerBase
    {
        /// <summary>
        /// 构造函数依赖注入
        /// </summary>
        private IProductService _productService;
        private MongoCRUD<Browse> _mongo;
        private readonly IJwtHelper _jwtService;
        private IUserService _userService;
        /// <summary>
        /// 函数依赖注入
        /// </summary>
        /// <param name="productService"></param>
        /// <param name="mongo"></param>
        /// <param name="jwtService"></param>
        /// <param name="userService"></param>
        public ProductController(IProductService productService, MongoCRUD<Browse> mongo, IJwtHelper jwtService, IUserService userService)
        {
            _productService = productService;
            _mongo = mongo;
            _jwtService = jwtService;
            _userService = userService;
        }


        /// <summary>
        /// 商品显示查询分页
        /// </summary>
        /// <param name="pname">查询参数</param>
        /// <param name="pageIndex">页数</param>
        /// <param name="pageSize">条数</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Index(string pname = "", int pageIndex = 1, int pageSize = 3)
        {
            try
            {
                int totalCount;
                pname += "";
                List<Product> lst = _productService.GetProductsAsync(pname, pageIndex, pageSize, out totalCount);
                return Ok(new { data = lst, code = 0, msg = "", count = totalCount });
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 添加商品
        /// </summary>
        /// <param name="obj">参数</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> AddProduct([FromForm] ProductDto obj)
        {
            try
            {
                int n = await _productService.InsertAsync(obj);
                if (n > 0)
                {
                    return Ok(new { data = obj, code = 1 });
                }
                else
                {
                    return Ok(new { data = n, code = 0 });
                }
            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 图片上传
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult Upload(IFormFile file)
        {
            string rootdir = AppContext.BaseDirectory.Split(@"\bin\")[0];
            string fname = DateTime.Now.ToString("yyyyMMddHHmmssfff") + System.IO.Path.GetExtension(file.FileName);
            var path = rootdir + @"\static\images\" + fname; //拼接路径 
            using (System.IO.FileStream fileStream = System.IO.File.Create(path))
            {
                file.CopyTo(fileStream);
                fileStream.Flush(); //清空文件流
            }

            //找到图片
            Image image = Image.Load(path);
            //缩小图片
            image.Mutate(x => x.Resize(image.Width / 2, image.Height / 2));
            //生成缩略图 （保存路径+图片名称+图片类型）
            string rootdirthumbnail = AppContext.BaseDirectory.Split(@"\bin\")[0];
            string fnamethumbnail = DateTime.Now.ToString("yyyyMMddHHmmssfff") + "thumbnailing" + System.IO.Path.GetExtension(file.FileName);
            var paththumbnail = rootdir + @"\static\images\" + fname;
            //保存缩略图
            image.Save(paththumbnail);

            return Ok(new { newFileName = "http://localhost:8021/" + fname }); //将能访问新文件的网址回传给前端
        }

        /// <summary>
        /// 删除商品
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        [HttpDelete]
        public async Task<IActionResult> DelProduct(int id)
        {
            try
            {
                int n = await _productService.DeleAsync(id);
                if (n > 0)
                {
                    return Ok(new { data = n, code = 1 });
                }
                else
                {
                    return Ok(new { data = n, code = 0 });
                }
            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 反填商品
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> Fill(int id)
        {
            try
            {
                //throw new Exception();
                Log4netHelper.Info($"用户进行操作");
                Product n = await _productService.FillAsync(id);
                return Ok(new { data = n, code = 1 });
            }
            catch (Exception ex)
            {
                Log4netHelper.Debug(ex.Message);
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 商品详情
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Fills(int id)
        {
            try
            {
                Log4netHelper.Info($"用户进行操作");
                ProductDto n = _productService.FillsAsync(id);
                return Ok(new { data = n, code = 1 });
            }
            catch (Exception ex)
            {
                Log4netHelper.Debug(ex.Message);
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 添加浏览
        /// </summary>
        /// <param name="id"></param>
        /// <param name="uid"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult Browse(int id, int uid)
        {
            ProductDto product = _productService.FillsAsync(id);
            _mongo.Create(new Browse()
            {
                Uid = uid,
                Pid = product.ProId,
                CreateTimes = DateTime.Now
            });
            return Ok("添加成功");
        }

        /// <summary>
        /// 创建浏览记录
        /// </summary>
        /// <param name="pid"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult CreateBrowse([FromForm] string pid, [FromForm] string token)
        {
            string id = token.Remove(0, 7);
            Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
            _jwtService.GetClaimFtomToken(id, out keyValuePairs);
            string openId = keyValuePairs["openid"];
            //根据ID查
            List<WeiXinLoginResult> lst = _userService.GetUsers(openId);
            if (lst.Count == 0)
            {
                return Ok(new { msg = "必须先登录" });
            }
            else
            {
                //获取用户主键ID
                int uid = lst[0].WeiXinId;
                //存入数据库
                Browse(Convert.ToInt32(pid), uid);
            }
            return Ok(new { msg = "浏览记录成绩成功" });
        }

        ///// <summary>
        ///// 浏览记录显示
        ///// </summary>
        ///// <returns></returns>
        //[HttpGet]
        //public ActionResult<List<Browse>> Get() =>
        //    _mongo.Get();

        /// <summary>
        /// 用户ID查询
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        [HttpGet]
        public List<Browse> UserQuery(int uid)
        {
            return _mongo.GetOne(x => x.Uid == uid);
        }

        /// <summary>
        /// 根据ID查找商品信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public List<Product> ProductQuery(string b)
        {
            return _productService.Products(b);
        }

        /// <summary>
        /// 查询浏览记录
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetBrowse(string token)
        {
            string tokens = token.Remove(0, 7);
            Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
            _jwtService.GetClaimFtomToken(tokens, out keyValuePairs);
            string openId = keyValuePairs["openid"];
            //根据ID查
            List<WeiXinLoginResult> lst = _userService.GetUsers(openId);
            if (lst.Count == 0)
            {
                return Ok(new { msg = "必须先登录" });
            }
            else
            {
                //获取用户主键ID
                int uid = lst[0].WeiXinId;
                List<Browse> list = this.UserQuery(uid);
                string a = "";
                //循环浏览记录表
                foreach (var item in list)
                {
                    //将循环的商品ID拼接
                    a += "," + item.Pid;
                }
                string b = a.Substring(1, a.Length - 1);
                List<Product> lists = this.ProductQuery(b);
                return Ok(new { data = list, datas = lists });
            }
        }

        /// <summary>
        /// 修改商品
        /// </summary>
        /// <param name="obj">参数</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> UptProduct([FromForm] ProductDto obj)
        {
            try
            {
                int n = await _productService.UptAsync(obj);
                if (n > 0)
                {
                    return Ok(new { data = n, code = 1 });
                }
                else
                {
                    return Ok(new { data = n, code = 0 });
                }
            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 加入回收站
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> RecycAsync(int id)
        {
            try
            {
                int n = await _productService.RecycAsync(id);
                if (n > 0)
                {
                    return Ok(new { data = n, code = 1 });
                }
                else
                {
                    return Ok(new { data = n, code = 0 });
                }
            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 回收站显示分页
        /// </summary>
        /// <param name="pageIndex">页数</param>
        /// <param name="pageSize">条数</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Indexs(int pageIndex = 1, int pageSize = 3)
        {
            try
            {
                int totalCount;
                List<Product> lst = _productService.GetRecycAsync(pageIndex, pageSize, out totalCount);
                return Ok(new { data = lst, code = 0, msg = "", count = totalCount });
            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 还原回收站
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> ResetAsync(int id)
        {
            try
            {
                int n = await _productService.ResetAsync(id);
                if (n > 0)
                {
                    return Ok(new { data = n, code = 1 });
                }
                else
                {
                    return Ok(new { data = n, code = 0 });
                }
            }
            catch (Exception ex)
            {

                throw new Exception(ex.Message);
            }
        }

    }
}
